﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using JSON;
using System.Web.Configuration;
using System.Web;
using Facebook_Graph_Toolkit.FacebookObjects;
using System.Text.RegularExpressions;

namespace Facebook_Graph_Toolkit {
    /// <summary>
    /// The class should be inherited in a .aspx page in a Facebook Iframe Application
    /// </summary>
    public class CanvasPage : System.Web.UI.Page {

        #region Login Settings
        /// <summary>
        /// Whether the user is required to authorize the application to view this page
        /// </summary>
        public bool RequireLogin = false;
        /// <summary>
        /// The user will be prompted to grant these Extended Permissions at authorization
        /// </summary>
        public string ExtendedPermissions = "";
        /// <summary>
        /// Whether or not to check if the user has already granted the extended permissions. If not, the library will redirect the user to do so.
        /// </summary>
        public bool CheckExtendedPermissions = false;
        #endregion

        #region ApiData
        private GraphApi.Api _Api = null;
        private string _UserID = null;
        /// <summary>
        ///Stores the current Access Token and provides methods to make Api calls
        /// </summary>
        public GraphApi.Api Api {
            get {
                if (_Api == null) throw new Facebook_Graph_Toolkit.RequiredLoginException();
                return _Api;
            }
        }

        /// <summary>
        /// The UserID of the current Facebook user
        /// </summary>
        public string FBUserID
        {
            get
            {
                if (_Api == null) throw new Facebook_Graph_Toolkit.RequiredLoginException();
                return _UserID;
            }
        }

        /// <summary>
        /// Indicates whether the user has authorized the application
        /// </summary>
        public bool IsAuthorized { get; private set; }

        /// <summary>
        /// Basic data about the user who is browsing this Iframe Application
        /// </summary>
        public BasicUserData UserData { get; private set; }
        #endregion

        /// <summary>
        /// Manages Facebook Application configuration of this page
        /// </summary>
        public FacebookAppConfig FacebookAppConfig = new FacebookAppConfig();

        /// <summary>
        /// Event handler of 'OnLoad' event
        /// </summary>
        /// <param name="e"></param>
        protected override void OnLoad(EventArgs e) {
            FacebookAppConfig.GetDefaultConfig();

            if (!IsPostBack) {
                string SignedRequest = HttpContext.Current.Request["signed_request"];
                if (SignedRequest == null) {
                    throw new FacebookException("Cannot find Facebook POST data as expected. Make sure you're viewing this page in a Facebook Iframe Application.");
                }
  
                JsonObject JO = Helpers.Common.ParseSignedRequest(SignedRequest,FacebookAppConfig.FacebookAppSecret);

                if (JO["user_id"] != null)
                {
                    _Api = new GraphApi.Api((string)JO["oauth_token"], Helpers.Common.UnixTimestampToDateTime((int)JO["expires"]));
                    _UserID = JO["user_id"].ToString();
                    IsAuthorized = true;

                    ViewState["GraphApi"] = _Api;
                    ViewState["FBUserID"] = _UserID;
                    ViewState["FBAuthorized"] = true;
                }
                else IsAuthorized = false;
                UserData = new BasicUserData((JsonObject)JO["user"]);
            } else {
                _Api = (GraphApi.Api)ViewState["GraphApi"];
                _UserID=(string)ViewState["FBUserID"];

                if (_Api != null) IsAuthorized = true;
                else IsAuthorized = true;
            }

            bool RedirectForExtendedPermission = false;
            if (_Api != null&&CheckExtendedPermissions&&!string.IsNullOrEmpty(ExtendedPermissions.Trim())) {
                JsonArray JA = Helpers.ApiCaller.FqlFresh(string.Format("SELECT {0} FROM permissions WHERE uid = me()",ExtendedPermissions),_Api.AccessToken);
                JsonObject JO = (JsonObject)JA[0];
                foreach (KeyValuePair<string, object> KVP in JO) {
                    if ((int)KVP.Value == 0) {
                        RedirectForExtendedPermission = true;
                        break;
                    }
                }
            }

            if ((_Api==null && RequireLogin)||RedirectForExtendedPermission) {
                RedirectToFacebookAuthorization();
            }

            base.OnLoad(e);
        }

        /// <summary>
        /// Redirect the user to authorize the Application
        /// </summary>
        protected void RedirectToFacebookAuthorization() {
            string RedirectUrl = FacebookAppConfig.FacebookAppAddress + FacebookAppConfig.PostAuthorizeRedirectURL;
            string AuthorizeUrl = string.Format("https://graph.facebook.com/oauth/authorize?client_id={0}&redirect_uri={1}&scope={2}", FacebookAppConfig.FacebookAppID, RedirectUrl, ExtendedPermissions);
            Helpers.IframeHelper.IframeRedirect(AuthorizeUrl, false, true);
        }

        /// <summary>
        /// Resolve an address that is relative to the Canvas Address to absolute address
        /// </summary>
        /// <param name="RelativeAddress">Address relative to Canvas Address</param>
        /// <returns>Absolute address</returns>
        public string ResolveCanvasRelativeAddress(string RelativeAddress) {
            return FacebookAppConfig.FacebookAppAddress + RelativeAddress;
        }
        /// <summary>
        /// Captures the AppRequest IDs from the querystring
        /// </summary>
        /// <returns>An IList containing the AppRequest IDs</returns>
        public IList<string> CaptureAppRequestIDs() {
            IList<string> IDs = new List<string>();
            foreach (string key in Request.QueryString) {
                Match M = Regex.Match(key, "request_ids" + Regex.Escape("[") + "(?<index>\\d)]");
                if (M.Success) IDs.Add(Request.QueryString[key]);
            }
            return IDs;
        }
    }
}
